#pragma once

#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include <mutex>
#include "spdlog/spdlog.h"
#include "order.h"
#include "order_book.h"
#include "order_executor.h"

class SmartOrderRouter {
public:
    virtual ~SmartOrderRouter() = default;
    virtual bool routeOrder(const Order& order) = 0;
    virtual bool batchRouteOrders(const std::vector<Order>& orders) = 0;
    virtual void updateOrderBook(const OrderBook& book) = 0;
};

class SmartOrderRouterImpl : public SmartOrderRouter {
public:
    struct LiquidityCheckResult {
        int64_t available = 0;
        bool sufficient = false;
    };
    
    struct SlippageCheckResult {
        double actual = 0.0;
        bool acceptable = false;
    };

    explicit SmartOrderRouterImpl(std::shared_ptr<OrderExecutor> executor);
    
    bool routeOrder(const Order& order) override;
    bool batchRouteOrders(const std::vector<Order>& orders) override;
    void updateOrderBook(const OrderBook& book) override;
    
private:
    LiquidityCheckResult checkLiquidity(const Order& order, const OrderBook& book);
    SlippageCheckResult checkSlippage(const Order& order, const OrderBook& book);
    
    std::shared_ptr<OrderExecutor> executor_;
    std::unordered_map<std::string, OrderBook> order_books_;
    std::mutex books_mutex_;
    
    const double max_slippage_ = 0.01;  // 1%
    const int64_t min_liquidity_ = 10000;
};